package com.yanqu.road.server.manager.match;

import com.yanqu.road.entity.config.match.MatchInfo;
import com.yanqu.road.entity.match.MatchData;
import com.yanqu.road.entity.match.UserMatchData;
import com.yanqu.road.entity.rank.cross.CrossUserRank;
import com.yanqu.road.entity.servercenter.MatchServerGroup;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.pb.variety.VarietyProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manger.MatchServerGroupMgr;
import com.yanqu.road.server.pb.CrossVarietyPb;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.date.DateHelper;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author ：zfr
 * @date ：2021/2/4 10:17
 * 分组赛事
 */
public class GroupMatch {
    /**
     * 分组id
     */
    private long groupId;
    /**
     * 杂艺map
     * timeId - id - match
     * 时间id - 自增id - 杂艺
     */
    private Map<Integer, Map<Integer, Match>> matchMap;
    /**
     * 周排行
     * weekId - matchRankModel
     */
    private Map<Integer, MatchWeekRankModel> rankModelMap;

    public Map<Integer, MatchWeekRankModel> getRankModelMap() {
        return rankModelMap;
    }

    public GroupMatch(long groupId, Map<Integer, Map<Integer, Match>> matchMap, Map<Integer, MatchWeekRankModel> rankModelMap) {
        this.groupId = groupId;
        this.matchMap = matchMap;
        this.rankModelMap = rankModelMap;
    }

    public long getGroupId() {
        return groupId;
    }

    /**
     * 检查赛事初始化
     */
    public int checkMatchInit() {
        int timeId = Integer.parseInt(DateHelper.getPyyyyMMddDateString(System.currentTimeMillis() / 1000));
        synchronized (matchMap) {
            boolean isInit = false;
            if (!matchMap.containsKey(timeId)) {
                matchMap.put(timeId, new ConcurrentHashMap<>());
            }
            int openNum = 0;
            for (Integer levelOpenNum : CrossMatchConfigMgr.matchLevelNumMap.values()) {
                openNum += levelOpenNum;
            }
            openNum += GameConfig.ALL_OCCUPATION_VARIETY_OPEN_NUM;
            //赛事初始化数量不够
            if (matchMap.get(timeId).size() < openNum) {
                //n个赛事等级
                for (int i = 1; i <= CrossMatchConfigMgr.matchLevelNumMap.size(); i++) {
                    int num = 0;
                    for (Match match : matchMap.get(timeId).values()) {
                        if (match.getMatchData().getLevel() == i && match.getMatchData().getType() != 0) {
                            num++;
                        }
                    }
                    //各个等级赛事的场数是否足够
                    if (num < CrossMatchConfigMgr.matchLevelNumMap.get(i)) {
                        int perNum = CrossMatchConfigMgr.matchLevelNumMap.get(i) - num;
                        for (int j = 0; j < perNum; j++) {
                            MatchInfo matchInfo = CrossMatchConfigMgr.randomMatch(matchMap.get(timeId), i, false);
                            isInit = initMatch(timeId, matchInfo) || isInit;
                        }
                    }
                }
                //再初始化必出杂艺(全职业高等级杂艺)
                int num = 0;
                for (Match match : matchMap.get(timeId).values()) {
                    if (match.getMatchData().getType() == 0) {
                        num++;
                    }
                }
                int allOccupationOpenNum = GameConfig.ALL_OCCUPATION_VARIETY_OPEN_NUM;
                int perNum = allOccupationOpenNum - num;
                for (int i = 0; i < perNum; i++) {
                    MatchInfo matchInfo = CrossMatchConfigMgr.randomMatch(matchMap.get(timeId), CrossMatchConfigMgr.VarietyHighLevel, true);
                    isInit = initMatch(timeId, matchInfo) || isInit;
                }
            }


            //有新杂艺生成 通知在线玩家
            if (isInit) {
                MatchServerGroup matchServerGroup = MatchServerGroupMgr.getServerGroupMap().get(groupId);
                if (matchServerGroup != null) {
                    for (Long serverId : matchServerGroup.getServerList()) {
                        VarietyProto.SyncVarietyListRespMsg.Builder syncVarietyBuilder = getSyncVarietyBuilder(0L, serverId);
                        MessageHelper.sendPacket(serverId, 0, YanQuMessageUtils.buildMessage(GameProtocol.S_VARIETY_RECEIVE_CROSS_SYNC_VARIETY_LIST, syncVarietyBuilder));
                    }
                }
            }
        }
        return timeId;
    }

    /**
     * 初始化赛事
     * @param timeId 时间id
     */
    private boolean initMatch(int timeId, MatchInfo matchInfo) {
        if (matchInfo == null) {
            return false;
        }
        Match match = new Match();
        MatchData data = new MatchData();
        data.setGroupId(groupId);
        List<Long> serverList = new ArrayList<>();
        serverList.add(groupId);
        data.setServerList(serverList);
        data.setOverForGroupChange(false);
        data.setTimeId(timeId);
        data.setLevel(matchInfo.getLevel());
        data.setType(matchInfo.getOccupation());
        data.setId(CrossMatchMgr.getNextId());
        data.setMatchId(matchInfo.getId());
        data.setInsertOption();
        match.setMatchData(data);
        matchMap.get(timeId).put(data.getId(), match);
        return true;
    }

    /**
     * 派遣队伍
     * @param serverId 服务器id
     * @param userId   玩家id
     * @param msg
     * @param respMsg
     */
    public void dispatchTeam(long serverId, long userId, VarietyProto.DispatchTeamCrossReqMsg msg, VarietyProto.DispatchTeamCrossRespMsg.Builder respMsg) {
        Match match = getMatch(msg.getId());
        if (match == null) {
            respMsg.setRet(GameErrorCode.E_VARIETY_VARIETY_NOT_FOUND);
            return;
        }
        match.dispatchTeam(serverId, userId, msg, respMsg);
        //派遣成功 同步派遣队伍数据给客户端
        if (respMsg.getRet() == 0) {
            syncTeamList(userId, serverId);
        }
    }

    /**
     * 发奖
     *
     * @param serverId          区服id
     * @param userId            玩家id
     * @param getRewardDataList 派遣时间
     * @param respMsg
     */
    public void getReward(long serverId, long userId, List<VarietyProto.GetRewardData> getRewardDataList, VarietyProto.GetRewardCrossRespMsg.Builder respMsg) {
        for (VarietyProto.GetRewardData getRewardData : getRewardDataList) {
            Map<Integer, Match> map = matchMap.get(getRewardData.getDispatchTimeId());
            if (map != null) {
                Match match = map.get(getRewardData.getId());
                if (match != null) {
                    match.getReward(serverId, userId, respMsg);
                }
            }
        }
    }

    /**
     * 获取当前赛事
     * @param id 自增id
     * @return  赛事
     */
    private Match getMatch(int id) {
        int timeId = getCurrentTimeId();
        if (matchMap.containsKey(timeId)) {
            return matchMap.get(timeId).get(id);
        }
        return null;
    }

    /**
     * 同步杂艺列表给客户端
     * @param playerId  玩家id
     * @param serverId  服务器id
     */
    public void syncVarietyList(long playerId, long serverId) {
        VarietyProto.SyncVarietyListRespMsg.Builder builder = getSyncVarietyBuilder(playerId, serverId);
        YanQuMessage message = YanQuMessageUtils.buildMessage(ClientProtocol.U_VARIETY_SYNC_VARIETY_LIST, builder);
        MessageHelper.sendPacket(serverId, playerId, message);
    }

    /**
     * 获取同步杂艺列表的数据
     * @param playerId 玩家id
     * @param serverId 服务器id
     * @return
     */
    public VarietyProto.SyncVarietyListRespMsg.Builder getSyncVarietyBuilder(long playerId, long serverId) {
        VarietyProto.SyncVarietyListRespMsg.Builder builder = VarietyProto.SyncVarietyListRespMsg.newBuilder();
        int timeId = getCurrentTimeId();
        Map<Integer, Match> map = matchMap.get(timeId);
        if (map != null) {
            for (Match match : map.values()) {
                builder.addVariety(CrossVarietyPb.parseVariety(match, playerId, serverId));
            }
        }
        return builder;
    }

    /**
     * 同步杂艺玩家派遣队伍给客户端
     * @param playerId 玩家id
     * @param serverId 区服id
     */
    public void syncTeamList(long playerId, long serverId) {
        VarietyProto.SyncUserTeamListRespMsg.Builder builder = VarietyProto.SyncUserTeamListRespMsg.newBuilder();
        List<Integer> allTimeIds = getThisWeekAllTimeId();
        for (int timeId : allTimeIds) {
            Map<Integer, Match> map = matchMap.get(timeId);
            if (map != null) {
                for (Match match : map.values()) {
                    UserMatchData userMatchData = match.getUserMatchData(serverId, playerId);
                    if (userMatchData != null) {
                        builder.addUserDispatchTeam(CrossVarietyPb.parseTeam(match, userMatchData, match.getUserRank(userMatchData)));
                    }
                }
            }
        }
        YanQuMessage message = YanQuMessageUtils.buildMessage(ClientProtocol.U_VARIETY_SYNC_TEAM_LIST, builder);
        MessageHelper.sendPacket(serverId, playerId, message);
    }

    public List<Integer> getThisWeekAllTimeId() {
        int nowTimeId = Integer.parseInt(DateHelper.getPyyyyMMddDateString(System.currentTimeMillis() / 1000));
        List<Integer> allTimeIds = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        for (int i = 0; i < 7; i++) {
            int timeId = Integer.parseInt(DateHelper.getPyyyyMMddDateString(cal.getTimeInMillis() / 1000));
            if (timeId <= nowTimeId) {
                allTimeIds.add(timeId);
            }
            cal.add(Calendar.DAY_OF_YEAR, 1);
        }
        return allTimeIds;
    }

    /**
     * 读库初始化 matchMap
     * @param data 杂艺数据
     * @param integerMapMap
     * @param integerLinkedListMap
     */
    public void initMatchMap(MatchData data, Map<Integer, Map<Integer, List<UserMatchData>>> integerMapMap, Map<Integer, LinkedList<CrossUserRank>> integerLinkedListMap) {
        synchronized (matchMap) {
            if (!matchMap.containsKey(data.getTimeId())) {
                matchMap.put(data.getTimeId(), new ConcurrentHashMap<>());
            }
            Match match = new Match();
            match.setMatchData(data);
            if (integerMapMap != null && integerMapMap.get(data.getTimeId()) != null && integerMapMap.get(data.getTimeId()).get(data.getId()) != null) {
                match.initUserDataMap(integerMapMap.get(data.getTimeId()).get(data.getId()));
            }
            matchMap.get(data.getTimeId()).put(data.getId(), match);
        }
        synchronized (rankModelMap) {
            if (integerLinkedListMap != null) {
                for (Map.Entry<Integer, LinkedList<CrossUserRank>> entry : integerLinkedListMap.entrySet()) {
                    MatchWeekRankModel model = new MatchWeekRankModel(groupId, entry.getKey());
                    model.setRankNum(getMatchWeekRankMaxCount());

                    model.setRankList(entry.getValue());
                    rankModelMap.put(entry.getKey(), model);
                }
            }
        }
    }

    /**
     * 最大排名
     * @return
     */
    public int getMatchWeekRankMaxCount() {
        int rankMax = GameConfig.RANK_DEFAULT_MAX_COUNT;
        try {
            int max = 0;
            String rewardStr = GameConfig.VARIETY_WEEK_RANK_REWARD;
            String[] arr = rewardStr.split("\\|");
            for (String params : arr) {
                String[] split = params.split("#");
                String[] paramList = split[0].split(",");
                if (max < Integer.parseInt(paramList[1])) {
                    max = Integer.parseInt(paramList[1]);
                }
            }
            return max;
        } catch (Exception e) {
            CrossMatchMgr.getLogger().error("getMatchMaxRank error !!");
            return rankMax;
        }
    }

    public void changeUserRank(int weekId, CrossUserRank crossUserRank) {
        synchronized (rankModelMap) {
            MatchWeekRankModel model = rankModelMap.get(weekId);
            if (model == null) {
                model = new MatchWeekRankModel(groupId, weekId);
                model.setRankNum(getMatchWeekRankMaxCount());
                rankModelMap.put(weekId, model);
            }
            model = rankModelMap.get(weekId);
            if (model != null) {
                model.rankChange(crossUserRank);
            }
        }
    }

    public void save() {
        for (Map<Integer, Match> map : matchMap.values()) {
            for (Match match : map.values()) {
                match.save();
            }
        }

        for (MatchWeekRankModel model : rankModelMap.values()) {
            model.saveRankList();
        }
    }

    /**
     * 分组变动提前结束当前进行中的杂艺
     */
//    public void overForGroupChange() {
//        synchronized (matchMap) {
//            int timeId = Integer.parseInt(DateHelper.getPyyyyMMddDateString(System.currentTimeMillis() / 1000));
//            Map<Integer, Match> map = matchMap.get(timeId);
//            if (map != null) {
//                for (Match match : map.values()) {
//                    if (MatchServerGroupMgr.getServerGroupMap().get(match.getMatchData().getGroupId()) == null
//                            || MatchServerGroupMgr.getServerGroupMap().get(match.getMatchData().getGroupId()).getMatchState() == 0
//                            || !LongListCompare(match.getMatchData().getServerList(), MatchServerGroupMgr.getServerGroupMap().get(match.getMatchData().getGroupId()).getServerList())) {
//                        match.getMatchData().setOverForGroupChange(true);
//                    }
//                }
//            }
//        }
//    }

    /**
     * 比较两个list 忽略顺序
     * @param list1
     * @param list2
     * @return
     */
    public static boolean LongListCompare(List<Long> list1, List<Long> list2){
        if(null == list1 || null == list2){
            return false;
        }
        if(list1.size() != list2.size()){
            return false;
        }
        List<Long> tempList = new ArrayList<>(list2);
        for(Long value : list1){
            if(!tempList.contains(value)){
                return false;
            }
            tempList.remove(value);
        }
        return true;
    }

    /**
     * 同步杂艺详细数据
     * @param msg
     * @param respMsg
     */
    public void syncVarietyDetailData(VarietyProto.SyncVarietyDetailReqMsg msg, VarietyProto.SyncVarietyDetailRespMsg.Builder respMsg) {
        Match match = getMatch(msg.getId());
        if (match == null) {
            return;
        }
        match.syncVarietyDetailData(respMsg);
    }

    /**
     * 获取杂艺排行列表
     * @param id 唯一id
     * @param serverId
     * @param playerId
     * @param respMsg
     */
    public void getVarietyRank(int id, long serverId, long playerId, VarietyProto.GetVarietyRankRespMsg.Builder respMsg) {
        Match match = getMatch(id);
        if (match == null) {
            respMsg.setRet(GameErrorCode.E_VARIETY_VARIETY_NOT_FOUND);
            return;
        }
        respMsg.setVariety(CrossVarietyPb.parseVariety(match, playerId, serverId));
        match.getVarietyRank(serverId, playerId, respMsg);
    }

    /**
     * 获取当前时间应对应的timeId
     * @return
     */
    private int getCurrentTimeId() {
        Calendar cal = Calendar.getInstance();
        if (CrossMatchConfigMgr.isGetLastDayMatch()) {
            cal.add(Calendar.DATE, -1);
        }
        return Integer.parseInt(DateHelper.getPyyyyMMddDateString(cal.getTimeInMillis() / 1000));
    }

    /**
     * 红点同步
     * @param serverId
     * @param playerId
     * @param respMsg
     */
    public void syncRedPot(long serverId, long playerId, VarietyProto.VarietyRedPot.Builder respMsg) {
        if (rankModelMap.get(respMsg.getWeekId()) == null || rankModelMap.get(respMsg.getWeekId()).getRankList().size() == 0) {
            respMsg.setWeekGetReward(false);
        }
        int timeId = Integer.parseInt(DateHelper.getPyyyyMMddDateString(System.currentTimeMillis() / 1000));
        if (matchMap.containsKey(timeId)) {
            for (Match match : matchMap.get(timeId).values()) {
                if (match.isJoin(serverId, playerId) && match.getMatchData().isOverForGroupChange()) {
                    respMsg.setGetReward(true);
                    return;
                }
            }
        }
    }

    public MatchWeekRankModel getRankListModel(int weekId) {
        return rankModelMap.get(weekId);
    }

    public void removeOutTimeData(int monthBefore) {
        synchronized (rankModelMap) {
            for (Map.Entry<Integer, MatchWeekRankModel> entry : rankModelMap.entrySet()) {
                if (entry.getKey() < monthBefore) {
                    rankModelMap.remove(entry.getKey());
                }
            }
        }
    }

    /**
     * 同步门客赚钱
     * @param serverId
     * @param playerId
     * @param syncPatronsTempList
     */
    public void syncPatronsAbility(long serverId, long playerId, List<VarietyProto.SyncPatronsTemp> syncPatronsTempList) {
        int timeId = Integer.parseInt(DateHelper.getPyyyyMMddDateString(System.currentTimeMillis() / 1000));
        if (matchMap.containsKey(timeId)) {
            for (Match match : matchMap.get(timeId).values()) {
                if (match.isJoin(serverId, playerId)) {
                    match.syncPatronsAbility(serverId, playerId, syncPatronsTempList);
                }
            }
        }
    }
}
